
package net.towee.server.authentication.impl;

import javax.servlet.http.HttpSession;

import net.towee.model.account.AccountData;
import net.towee.model.account.AccountIdentity;
import net.towee.model.account.impl.AccountDataImpl;
import net.towee.model.account.impl.AccountIdentityImpl;
import net.towee.server.CoreSettings;
import net.towee.server.authentication.PasswordDigest;
import net.towee.server.authentication.SessionAuthManager;
import net.towee.server.persistence.AccountStore;
import net.towee.server.util.RandomBase64Generator;
import net.towee.shared.exceptions.PersistenceException;

import org.apache.vysper.xmpp.addressing.Entity;
import org.apache.vysper.xmpp.addressing.EntityImpl;
import org.bson.types.ObjectId;
import org.eclipse.jetty.server.SessionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.inject.Inject;
import com.google.inject.name.Named;

public class SessionAuthManagerImpl implements SessionAuthManager {
	private static final Logger LOG = LoggerFactory.getLogger(SessionAuthManagerImpl.class);
	private static final String USER_ID_FIELD = "user";

	private final AccountStore accountStore;
	private final SessionManager jettySessionManager;
	private final boolean debug;
	private String testAccount;

	@Inject
	public SessionAuthManagerImpl(AccountStore accountStore,
			org.eclipse.jetty.server.SessionManager jettySessionManager,
			@Named(CoreSettings.DEBUG) boolean debug) {
		Preconditions.checkNotNull(accountStore, "Null account store");
		Preconditions.checkNotNull(jettySessionManager, "Null jetty session manager");
		
		this.accountStore = accountStore;
		this.jettySessionManager = jettySessionManager;
		this.debug = debug;
	
		if(debug) 
			createTestAccount();
	}
	
	private void createTestAccount(){
		AccountIdentity id = new AccountIdentityImpl(new ObjectId().toString());
		id.setFirstName("Вася");
		id.setLastName("Пупкин");
		
		AccountData acc = new AccountDataImpl(id);
		PasswordDigest dgst = new PasswordDigest("123".toCharArray());
		acc.setSaltDigest(dgst.getSalt(), dgst.getDigest());
		acc.getAttachedAccounts().addAccount("123123", "111");
		acc.addEmail("viiv.c58"+new RandomBase64Generator().next(5)+"@gmail.com");		
		accountStore.createAccount(acc);
		this.testAccount = id.getId(); 
	}

	@Override
	public String getLoggedInUser(HttpSession session, String coockieRememberId) {
		if(debug)
			return testAccount;
		
		if (session != null) {
			String id = (String) session.getAttribute(USER_ID_FIELD);
			
			if( id == null && !Strings.isNullOrEmpty(coockieRememberId) ) {
				id = accountStore.getAccountByCookie( coockieRememberId );
				
				if(id != null) 
					setLoggedInUser(session, id);
			}
			
			return id;
		}
		else 
			return null;
	}

	@Override
	public void setLoggedInUser(HttpSession session, String id) {
		Preconditions.checkNotNull(session, "Session is null");
		Preconditions.checkNotNull(id, "Participant id is null");
		session.setAttribute(USER_ID_FIELD, id);
	}

	@Override
	public void logout(HttpSession session) {
		if (session != null) {
			session.removeAttribute(USER_ID_FIELD);
		}
	}

	@Override
	public HttpSession getSessionFromToken(String token) {
		Preconditions.checkNotNull(token);
		return jettySessionManager.getHttpSession(token);
	}

	@Override
	public boolean isLoggedIn(HttpSession session) {
		return getLoggedInUser(session, null) != null;
	}

	@Override
	public Entity getSessionJID(HttpSession session) {
		return new EntityImpl("test2", "localhost", null);
	}

	@Override
	public AccountData getLoggedInAccount(HttpSession session) {
		try {
			return accountStore.getAccountById( getLoggedInUser(session, null) );
		} catch (PersistenceException e) {
			return null;
		}
	}

}
